package com.future.network

import android.content.Context
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.NetworkRequest
import android.os.Build
import androidx.annotation.RequiresApi
import com.future.network.annotation.Network
import com.future.network.info.MethodManager
import com.future.network.info.NetworkInterface
import com.future.network.receiver.NetworkCallbackImpl
import com.future.network.utiles.DebugLogs
import java.lang.reflect.Method
import kotlin.collections.ArrayList

/**
 * 通过注解方式反射
 */
class NetWorkMonitorManager : NetworkInterface {
    private val networkList = hashMapOf<Any, List<MethodManager>>()
    private var networkCallbackImpl: NetworkCallbackImpl? = null
    private lateinit var context: Context
    private var isInit = false

    companion object {
        private var instance: NetWorkMonitorManager? = null
            get() {
                if (field == null) {
                    field = NetWorkMonitorManager()
                }
                return field
            }

        @Synchronized
        fun get(): NetWorkMonitorManager {
            return instance!!
        }
    }

    init {
        networkCallbackImpl = NetworkCallbackImpl()
    }


    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    private fun getNetworkCallBackImpl(): NetworkCallbackImpl {
        if (networkCallbackImpl == null) {
            networkCallbackImpl = NetworkCallbackImpl()
        }
        return networkCallbackImpl as NetworkCallbackImpl
    }

    /**
     * 初始化方法，初始网络监听，根据不同版本监听不同的处理
     */
    fun init(context: Context) {
        if (isInit) {
            DebugLogs.show("进行了多次初始化!")
            return
        }
        this.context = context.applicationContext
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {//版本大于26时
                connectivityManager.registerDefaultNetworkCallback(getNetworkCallBackImpl())
            }
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {//API 大于21时
                val builder = NetworkRequest.Builder()
                val request = builder.build()
                connectivityManager.registerNetworkCallback(request, getNetworkCallBackImpl())
            }
        }
        isInit = true
    }

    //解析类里面主机方法和类 针对Network注解方法解析
    override fun getAnnotationMethod(observer: Any): List<MethodManager> {
        val methodList = ArrayList<MethodManager>()
        //获取类中所有方法
        val methods = observer.javaClass.methods as Array<Method>
        var network: Network?
        var methodManager: MethodManager
        for (method in methods) {
            //返回此元素上存在的所有注释。（如果此元素没有注释，则返回长度为零的数组。）该方法的调用者可以随意修改返回的数组；这不会对其他调用者返回的数组产生任何影响。
            network = method.getAnnotation(Network::class.java)
            network?.let {
                //校验返回值
                val returnType = method.genericReturnType
                if ("void" != returnType.toString()) {
                    throw RuntimeException(method.name + " return type should be null ")
                }
                //校验参数
                val parameterTypes = method.parameterTypes
                if (parameterTypes.size != 1) {
                    throw RuntimeException(method.name + " arguments should be one ")
                }
                methodManager = MethodManager(
                    parameterTypes[0],
                    network.netType,
                    method
                )
                methodList.add(methodManager)
            }
        }
        return methodList
    }

    /**
     * 注册
     */
    override fun registerObserver(observer: Any) {
        var methodList = networkList[observer]
        if (methodList == null) {
            methodList = getAnnotationMethod(observer)
            networkList[observer] = methodList
        }
    }

    /**
     * 注销
     */
    override fun unRegisterObserver(observer: Any) {
        if (networkList.isNotEmpty()) {
            networkList.remove(observer)
        }
    }

    override fun unRegisterAllObserver() {
        if (networkList.isNotEmpty()) {
            networkList.clear()
        }
    }

    /**
     * 发送当前网络状态
     */
    override fun post(networkType: NetworkType) {
        //获取当前观察者的key
        val sets: Set<Any> = networkList.keys
        for (observer: Any in sets) {
            //遍历是否存在观察者
            val methodList = networkList[observer]
//            DebugLogs.show("网络事件开始发送" + methodList.toString())
            for (method: MethodManager in methodList!!) {
//                DebugLogs.show("网络事件开始发送" + methodList.size)
                if (method.type.isAssignableFrom(networkType::class.java)) {
                    if (method.networkType == networkType ||
                        networkType == NetworkType.NETWORK_NO ||
                        method.networkType == NetworkType.AUTO
                    ) {
                        invoke(method, observer, networkType)
                    }
                }
            }
        }
    }

    /**
     * 通过注册类的方法回执给当前方法
     */
    private fun invoke(methodManager: MethodManager, observer: Any, networkType: NetworkType) {
        try {
            val execute = methodManager.method
            //触发注解方法
            execute.invoke(observer, networkType)
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        }
    }
}